﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using YeePay = com.yeepay.bank;
using QianBuo.Lottery.Web.Models;
using Code.BLL;
using Code.Models;
using System.Collections;

namespace QianBuo.Lottery.Web.Controllers
{
    public class PayController : BaseController
    {
        //
        // GET: /Pay/

        public ActionResult Index(PayModels.PayModel model)
        {
            ModelState.Remove("Money");
            if (model == null)
                model = new PayModels.PayModel();
            return View(model);
        }

        [HttpPost]
        [ActionName("Index")]
        public ActionResult Index_Post(PayModels.PayModel model)
        {
            var min = CacheManage.OptionSite[Option_Site_Key.Site_AddMoney_Min].ToDouble(0);
            if (min > 0 && model.Money < min)
                ModelState.AddModelError("Money", "每次充值至少大于" + min);
            if (ModelState.IsValid)
            {
                if (model.PayType == PayType.ICBC_Manual)
                {
                    var result = ICBC_Manual(model.Money.Value);
                    if (!(result is EmptyResult))
                        return result;
                }
                else if(model.PayType==PayType.TenPays_Manual) 
                {
                    var result = TenPay_Manual(model.Money.Value);
                    if (!(result is EmptyResult))
                        return result;
                }
                else if (model.PayType == PayType.AliPays_Manual)
                {
                    var result = AilPay_Manual(model.Money.Value);
                    if (!(result is EmptyResult))
                        return result;
                }
                return View("Redirect", model);
            }
            return View(model);
        }


        public ActionResult CardPay()
        {
            if (!CacheManage.OptionSite[Option_Site_Key.Site_CardPay_Enable].ToBool(false))
                return Content(Url.Action("Index", "Pay").Redirect("点卡充值已关闭！"));
            var model = new PayModels.CardPayModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult CardPay(PayModels.CardPayModel model)
        {
            if (model != null && !string.IsNullOrEmpty(model.CheckCode) && !model.CheckCode.Equals(TempData["CardPay"] as string, StringComparison.CurrentCultureIgnoreCase))
                ModelState.AddModelError("CheckCode", "验证码输入不正确");
            if (ModelState.IsValid)
            {
                var CM = new CardManage();
                try
                {
                    int rs=CM.CardPay(model.Number, model.Password, LoginUserID);
                    if (rs > 0)
                        ViewData["msg"] = Url.Action("Detail", "Account", Url.Route(new { Serch = new { Type = "AddMoney" } })).Redirect("充值成功\\r\\n是否立即查看该记录?", Url.Action("CardPay"));
                    else
                        ViewData["msg"] = "操作失败，请稍后再试".AlertOffPage();
                }
                catch(AppException e)
                {
                    ModelState.AddModelError(e.Source, e.Message);
                }

            }
            return View(model);
        }

        public ActionResult Redirect(PayModels.PayModel model)
        {
            var min = CacheManage.OptionSite[Option_Site_Key.Site_AddMoney_Min].ToDouble(0);
            if (min > 0 && model.Money < min)
                ModelState.AddModelError("Money", "每次充值至少大于" + min);
            if (ModelState.IsValid)
            {
                var AM = new AddMoneyManage();
                Guid order;
                int rs = AM.BuildPayOrder(base.LoginUserID, model.Money.Value, model.PayType, out order);
                if (rs != 1)
                    ModelState.AddModelError("Error", "系统错误，请稍后再试！");
                else
                {
                    try
                    {
                        switch (model.PayType)
                        {
                            case PayType.YeePay:
                                return YeePayReq(order, model.Money.Value);
                            case PayType.AliPay:
                                return AliPayReq(order, model.Money.Value);
                            case PayType.TenPay:
                                return TenPayReq(order, model.Money.Value);
                            default:
                                throw new AppException();
                        }
                    }
                    catch
                    {
                        ModelState.AddModelError("Error", model.PayType.GetName() + "暂时不能使用");
                    }
                }
            }
            return Content(Url.Action("Index").Redirect(string.Join(",", ModelState.Where(p => p.Value.Errors.Count > 0).Select(p => p.Value.Errors[0].ErrorMessage).ToArray())));
        }

        #region 易宝支付
        [NonAction]
        public ActionResult YeePayReq(Guid order,double money)
        {
            if (!CacheManage.OptionSite[Option_Site_Key.Site_Pay_YeePay_Enable].ToBool(false))
                throw new ValidateException("未启用易宝支付平台");

            // 商户订单号,选填.
            //若不为""，提交的订单号必须在自身账户交易中唯一;为""时，易宝支付会自动生成随机的商户订单号.
            string p2_Order = order.ToString();

            // 支付金额,必填.
            //单位:元，精确到分.                   
            string p3_Amt = money.ToString("F2");

            //交易币种,固定值"CNY".
            string p4_Cur = "CNY";

            //商品名称
            //用于支付时显示在易宝支付网关左侧的订单产品信息.
            string p5_Pid = Request.Form["Pid"] ?? System.Configuration.ConfigurationManager.AppSettings["Pid"];

            //商品种类
            string p6_Pcat = Request.Form["Pcat"] ?? System.Configuration.ConfigurationManager.AppSettings["Pcat"];

            //商品描述
            string p7_Pdesc = Request.Form["Pdesc"] ?? System.Configuration.ConfigurationManager.AppSettings["Pdesc"];

            //商户接收支付成功数据的地址,支付成功后易宝支付会向该地址发送两次成功通知.
            string p8_Url = Url.Action("YeePayCallBack", "PayCalBack", null, null, Request.Url.DnsSafeHost);

            //送货地址
            //为“1”: 需要用户将送货地址留在易宝支付系统;为“0”: 不需要，默认为 ”0”.
            string p9_SAF = "0";

            //商户扩展信息
            //商户可以任意填写1K 的字符串,支付成功时将原样返回.	
            string pa_MP = base.LoginUserID.ToString();

            //银行编码
            //默认为""，到易宝支付网关.若不需显示易宝支付的页面，直接跳转到各银行、神州行支付、骏网一卡通等支付页面，该字段可依照附录:银行列表设置参数值.
            string pd_FrpId = Request.Form["pd_FrpId"];

            //应答机制
            //默认为"1": 需要应答机制;
            string pr_NeedResponse = "1";

            string url = YeePay.Buy.CreateBuyUrl(p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse);
            return Redirect(url);
        }
        #endregion

        #region 支付宝
        [NonAction]
        public ActionResult AliPayReq(Guid order, double money)
        {
            if (!CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Enable].ToBool(false))
                throw new ValidateException("未启用支付宝支付平台");

            var id = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_MerhantID].Value;
            if (string.IsNullOrEmpty(id))
                throw new AppException("未设置易宝支付商户ID");
            string _key = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Key].Value;
            if (string.IsNullOrEmpty(_key))
                throw new AppException("未设置易宝支付商户密钥");
            var des = new Code.Commen.DES();
            _key = des.DecryptString(_key, Salt.Keys.GetDesSalt().Key, Salt.Keys.GetDesSalt().Value);


            ///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的///////////////////////////
            //合作身份者ID
            string partner = id;
            //安全检验码             
            string key = _key;
            //签约支付宝账号或卖家支付宝帐户
            string seller_email = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Email].Value;
            //字符编码格式 目前支持 gb2312 或 utf-8
            string input_charset = "utf-8";                                          
            //交易过程中服务器通知的页面 要用 http://格式的完整路径，不允许加?id=123这类自定义参数
            string notify_url = Url.Action("AliPayCallBack_Server", "PayCalBack", null, null, Request.Url.DnsSafeHost);
            //付完款后跳转的页面 要用 http://格式的完整路径，不允许加?id=123这类自定义参数
            string return_url = Url.Action("AliPayCallBack", "PayCalBack", null, null, Request.Url.DnsSafeHost);
            //网站商品的展示地址，不允许加?id=123这类自定义参数
            string show_url = "";                     

            string sign_type = "MD5";                                                //加密方式 不需修改
            string antiphishing = "0";                                               //防钓鱼功能开关，'0'表示该功能关闭，'1'表示该功能开启。默认为关闭
            //一旦开启，就无法关闭，根据商家自身网站情况请慎重选择是否开启。
            //申请开通方法：联系我们的客户经理或拨打商户服务电话0571-88158090，帮忙申请开通
            //若要使用防钓鱼功能，建议使用POST方式请求数据

            ////////////////////////////////////////////////////////////////////////////////////////////////////

            ///////////////////////以下参数是需要通过下单时的订单数据传入进来获得////////////////////////////////
            //必填参数
            string out_trade_no = order.ToString();  //请与贵网站订单系统中的唯一订单号匹配
            //订单名称，显示在支付宝收银台里的“商品名称”里，显示在支付宝的交易管理的“商品名称”的列表里。
            string subject = Request.Form["Pid"] ?? System.Configuration.ConfigurationManager.AppSettings["Pid"];
            //订单描述、订单详细、订单备注，显示在支付宝收银台里的“商品描述”里
            string body = System.Configuration.ConfigurationManager.AppSettings["Pcat"];
            //订单总金额，显示在支付宝收银台里的“应付总额”里
            string total_fee = money.ToString("F2");

            //扩展功能参数——网银提前
            string paymethod = "bankPay";                                   //默认支付方式，四个值可选：bankPay(网银); cartoon(卡通); directPay(余额); CASH(网点支付)
            string defaultbank = "CMB";                                     //默认网银代号，代号列表见http://club.alipay.com/read.php?tid=8681379

            //扩展功能参数——防钓鱼
            string encrypt_key = "";                                        //防钓鱼时间戳，初始值
            string exter_invoke_ip = "";                                    //客户端的IP地址，初始值
            if (antiphishing == "1")
            {
                encrypt_key = AlipayClass.AlipayFunction.Query_timestamp(partner);
                exter_invoke_ip = "";                                       //获取客户端的IP地址，建议：编写获取客户端IP地址的程序
            }

            //扩展功能参数——其他
            string extra_common_param = "";        //自定义参数，可存放任何内容（除=、&等特殊字符外），不会显示在页面上
            string buyer_email = "";			                            //默认买家支付宝账号

            //扩展功能参数——分润(若要使用，请按照注释要求的格式赋值)
            string royalty_type = "";                                   //提成类型，该值为固定值：10，不需要修改
            string royalty_parameters = "";
            //提成信息集，与需要结合商户网站自身情况动态获取每笔交易的各分润收款账号、各分润金额、各分润说明。最多只能设置10条
            //提成信息集格式为：收款方Email_1^金额1^备注1|收款方Email_2^金额2^备注2
            //如：
            //royalty_type = "10";
            //royalty_parameters = "111@126.com^0.01^分润备注一|222@126.com^0.01^分润备注二";

            //扩展功能参数——自定义超时(若要使用，请按照注释要求的格式赋值)
            //该功能默认不开通，需联系客户经理咨询
            string it_b_pay = "";  //超时时间，不填默认是15天。八个值可选：1h(1小时),2h(2小时),3h(3小时),1d(1天),3d(3天),7d(7天),15d(15天),1c(当天)

            /////////////////////////////////////////////////////////////////////////////////////////////////////

            //构造请求函数
            var aliService = new AlipayClass.AlipayService(partner, seller_email, return_url, notify_url, show_url, out_trade_no, subject, body, total_fee, paymethod, defaultbank, encrypt_key, exter_invoke_ip, extra_common_param, buyer_email, royalty_type, royalty_parameters, it_b_pay, key, input_charset, sign_type);

            //GET方式传递
            string url = aliService.Create_url();
            //string sHtmlText = "<a href=" + url + "><img border='0' src='img/alipay.gif' /></a>";

            //POST方式传递，得到加密结果字符串。想POST方式传递，请把下面那句注释去掉。
            //string sHtmlText = aliService.Build_postform();

            //打印页面
            //lbOut_trade_no.Text = out_trade_no;
            //lbTotal_fee.Text = total_fee;
            //lbButton.Text = sHtmlText;

            return Redirect(url);
        }
        #endregion

        #region 财付通
        [NonAction]
        public ActionResult TenPayReq(Guid order,double money)
        {
            var pay = PayType.TenPay.GetDetail();

            if (!pay.Enable)
                throw new AppException("未启用财付通支付平台");
            if (string.IsNullOrEmpty(pay.MumberID))
                throw new AppException("未设置财付通商户ID");
            if (string.IsNullOrEmpty(pay.Key))
                throw new AppException("未设置财付通商户密钥");
            var des = new Code.Commen.DES();
            pay.Key = des.DecryptString(pay.Key, Salt.Keys.GetDesSalt().Key, Salt.Keys.GetDesSalt().Value);

            //商户号
            string bargainor_id = pay.MumberID;

            //密钥
            string key = pay.Key;

            //当前时间 yyyyMMdd
            string date = DateTime.Now.ToString("yyyyMMdd");

            //生成订单10位序列号，此处用时间和随机数生成，商户根据自己调整，保证唯一
            string strReq = "" + DateTime.Now.ToString("HHmmss") + tenpay.TenpayUtil.BuildRandomStr(4);

            //商户订单号，不超过32位，财付通只做记录，不保证唯一性
            string sp_billno = strReq;

            //财付通订单号，10位商户号+8位日期+10位序列号，需保证全局唯一
            string transaction_id = bargainor_id + date + strReq;
            string return_url = Url.Action("TenCallBack", "PayCalBack", null, null, Request.Url.DnsSafeHost);

            //商品名称
            string desc = Request.Form["Pid"] ?? System.Configuration.ConfigurationManager.AppSettings["Pid"]; 

            //创建PayRequestHandler实例
            var reqHandler = new tenpay.PayRequestHandler(this.ControllerContext.HttpContext);

            //设置密钥
            reqHandler.setKey(key);

            //初始化
            reqHandler.init();

            //-----------------------------
            //设置支付参数
            //-----------------------------
            reqHandler.setParameter("bargainor_id", bargainor_id);			//商户号
            reqHandler.setParameter("sp_billno", sp_billno);				//商家订单号
            reqHandler.setParameter("transaction_id", transaction_id);		//财付通交易单号
            reqHandler.setParameter("return_url", return_url);				//支付通知url
            reqHandler.setParameter("desc",desc);	//商品名称
            reqHandler.setParameter("total_fee", ((int)(money * 100)).ToString());		//商品金额,以分为单位
            reqHandler.setParameter("attach", order.ToString());            //商家数据包，原样返回
            reqHandler.setParameter("cs", "utf-8");


            reqHandler.setParameter("purchaser_id", "");                


            //用户ip,测试环境时不要加这个ip参数，正式环境再加此参数
            reqHandler.setParameter("spbill_create_ip",Request.UserHostAddress);

            //获取请求带参数的url
            string url = reqHandler.getRequestURL();

            return Redirect(url);
        }

        #endregion

        #region 工商银行转账
        [NonAction]
        public ActionResult ICBC_Manual(double money)
        {
            if (!CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_Enable].ToBool(false))
                throw new ValidateException("未启用工商银行转账充值功能");
            string siteid = System.Configuration.ConfigurationManager.AppSettings["SiteID"] ?? CacheManage.OptionSite[Option_Site_Key.Site_SiteID].Value;   
            Guid order;
            var AM = new AddMoneyManage();
            int rs = AM.BuildPayOrder(base.LoginUserID, money, PayType.ICBC_Manual, out order, siteid);
            if (rs != 1)
            {
                ModelState.AddModelError("Error", "系统错误，请稍后再试！");
                return new EmptyResult();
            }
            var detail = AM.Select<PayDetail, PayDetail>(s => s.FirstOrDefault(p => p.ID == order));
            var amn=CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Manual_MemberName];
            var amid=CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Manual_MemberID];
            var tmn=CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPay_Manual_MemberName];
                var tmid=CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPay_Manual_MemberID];
            var model = new PayModels.ICBC_ManualModel
            {
                Money = money,
                Order = detail.OrderID,
                SiteID = siteid,
                PayDetail = PayType.ICBC_Manual.GetDetail(),
               
            };

            double tmp;
            var ratio = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_ChargeRatio].ToDouble(out tmp) ? tmp / 100 : null as double?;
            var min = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_MinCharge].ToDouble(out tmp) ? tmp : null as double?;
            var max = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_MaxCharge].ToDouble(out tmp) ? tmp : null as double?;
            if (ratio.HasValue)
                model.SuccessMoney = Math.Round(model.Money * ratio.Value, 2);
            if (min.HasValue)
                model.SuccessMoney = Math.Max(model.SuccessMoney ?? min.Value, min.Value);
            if (ratio.HasValue && max.HasValue)
                model.SuccessMoney = Math.Min(model.SuccessMoney.Value, max.Value);

            return View("ICBC_Manual",model);
        }

        public ActionResult CancelOrder(long order, double? money, PayType paytype)
        {
            var AM = new AddMoneyManage();

            AM.CancelOrder(LoginUserID,order);
            return RedirectToAction("Index", new { money, paytype });
        }
        #endregion

        #region 支付宝转账
        public ActionResult AilPay_Manual(double money)
        {
            if (!CacheManage.OptionSite[Option_Site_Key.Site_Pay_Alipays_Manual_Enable].ToBool(false))
                throw new ValidateException("未启用支付宝转账充值功能");
            string siteid = System.Configuration.ConfigurationManager.AppSettings["SiteID"] ?? CacheManage.OptionSite[Option_Site_Key.Site_SiteID].Value;
            
            Guid order;
            var AM = new AddMoneyManage();
            int rs = AM.BuildPayOrder(base.LoginUserID, money, PayType.AliPays_Manual, out order, siteid);
            if (rs != 1)
            {
                ModelState.AddModelError("Error", "系统错误，请稍后再试！");
                return new EmptyResult();
            }
            var detail = AM.Select<PayDetail, PayDetail>(s => s.FirstOrDefault(p => p.ID == order));
            var amn=CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Manual_MemberName];
            var amid=CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Manual_MemberID];
            var tmn=CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPay_Manual_MemberName];
                var tmid=CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPay_Manual_MemberID];
            var model = new PayModels.AilPay_ManualModel
            {
                Money = money,
                Order = detail.OrderID,
                SiteID = siteid,
                AilPayDetail = PayType.AliPays_Manual.GetDetail(),
               
            };

            double tmp;
            var ratio = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_ChargeRatio].ToDouble(out tmp) ? tmp / 100 : null as double?;
            var min = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_MinCharge].ToDouble(out tmp) ? tmp : null as double?;
            var max = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_MaxCharge].ToDouble(out tmp) ? tmp : null as double?;
            if (ratio.HasValue)
                model.SuccessMoney = Math.Round(model.Money * ratio.Value, 2);
            if (min.HasValue)
                model.SuccessMoney = Math.Max(model.SuccessMoney ?? min.Value, min.Value);
            if (ratio.HasValue && max.HasValue)
                model.SuccessMoney = Math.Min(model.SuccessMoney.Value, max.Value);

            return View("AilPay_Manual", model);
        }

        public ActionResult AilPayCancelOrder(long order, double? money, PayType paytype)
        {
            var AM = new AddMoneyManage();

            AM.CancelOrder(LoginUserID, order);
            return RedirectToAction("Index", new { money, paytype });
        }
        #endregion

        #region 财付通转账
        public ActionResult TenPay_Manual(double money)
          {
              if (!CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPays_Manual_Enable].ToBool(false))
                  throw new ValidateException("未启用财付通转账充值功能");
              string siteid = System.Configuration.ConfigurationManager.AppSettings["SiteID"] ?? CacheManage.OptionSite[Option_Site_Key.Site_SiteID].Value;

              Guid order;
              var AM = new AddMoneyManage();
              int rs = AM.BuildPayOrder(base.LoginUserID, money, PayType.TenPays_Manual, out order, siteid);
              if (rs != 1)
              {
                  ModelState.AddModelError("Error", "系统错误，请稍后再试！");
                  return new EmptyResult();
              }
              var detail = AM.Select<PayDetail, PayDetail>(s => s.FirstOrDefault(p => p.ID == order));
              var amn = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Manual_MemberName];
              var amid = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Manual_MemberID];
              var tmn = CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPay_Manual_MemberName];
              var tmid = CacheManage.OptionSite[Option_Site_Key.Site_Pay_TenPay_Manual_MemberID];
              var model = new PayModels.TenPay_ManualModel
              {
                  Money = money,
                  Order = detail.OrderID,
                  SiteID = siteid,
                  TenPayDetail = PayType.TenPays_Manual.GetDetail(),

              };

              double tmp;
              var ratio = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_ChargeRatio].ToDouble(out tmp) ? tmp / 100 : null as double?;
              var min = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_MinCharge].ToDouble(out tmp) ? tmp : null as double?;
              var max = CacheManage.OptionSite[Option_Site_Key.Site_Pay_ICBC_Manual_MaxCharge].ToDouble(out tmp) ? tmp : null as double?;
              if (ratio.HasValue)
                  model.SuccessMoney = Math.Round(model.Money * ratio.Value, 2);
              if (min.HasValue)
                  model.SuccessMoney = Math.Max(model.SuccessMoney ?? min.Value, min.Value);
              if (ratio.HasValue && max.HasValue)
                  model.SuccessMoney = Math.Min(model.SuccessMoney.Value, max.Value);

              return View("TenPay_Manual", model);
          }

        public ActionResult TenPayCancelOrder(long order, double? money, PayType paytype)
        {
            var AM = new AddMoneyManage();

            AM.CancelOrder(LoginUserID, order);
            return RedirectToAction("Index", new { money, paytype });
        }
          #endregion

 
    }

    public class PayCalBackController : Controller
    { 
        /// <summary>
        /// 日志记录对象
        /// </summary>
        protected static log4net.ILog Log = Code.Commen.Log.GetLog("BaseController");

        [NonAction]
        public int CallBack(PayDetail pay)
        {
            int rs=-1;
            var AM = new AddMoneyManage();
            try
            {
                rs = AM.CallBackPay(pay);
            }
            catch (Exception e){
                if (Log.IsDebugEnabled)
                    Log.Debug(string.Format("在线充值:订单{0}回调出错,类型:{1},交易号:{2},金额:{3}", pay.ID, pay.PayType, pay.PayID, pay.Money), e);
                else if (Log.IsErrorEnabled)
                    Log.Error(string.Format("在线充值:订单{0}回调出错,类型:{1},交易号:{2},金额:{3},错误:{4}", pay.ID, pay.PayType, pay.PayID, pay.Money, e.Message));
                else if (Log.IsInfoEnabled)
                    Log.Info(string.Format("在线充值:订单{0}回调出错,类型:{1},交易号:{2},金额:{3},错误:{4}", pay.ID, pay.PayType, pay.PayID, pay.Money, e.Message));
            }
            return rs;


        }


        #region 易宝支付
        public ActionResult YeePayCallBack()
        {
            // 校验返回数据包
            YeePay.BuyCallbackResult result = YeePay.Buy.VerifyCallback(YeePay.FormatQueryString.GetQueryString("p1_MerId"), YeePay.FormatQueryString.GetQueryString("r0_Cmd"), YeePay.FormatQueryString.GetQueryString("r1_Code"), YeePay.FormatQueryString.GetQueryString("r2_TrxId"),
               YeePay.FormatQueryString.GetQueryString("r3_Amt"), YeePay.FormatQueryString.GetQueryString("r4_Cur"), YeePay.FormatQueryString.GetQueryString("r5_Pid"), YeePay.FormatQueryString.GetQueryString("r6_Order"), YeePay.FormatQueryString.GetQueryString("r7_Uid"),
               YeePay.FormatQueryString.GetQueryString("r8_MP"), YeePay.FormatQueryString.GetQueryString("r9_BType"), YeePay.FormatQueryString.GetQueryString("rp_PayDate"), YeePay.FormatQueryString.GetQueryString("hmac"));
            string message = null;
            if (string.IsNullOrEmpty(result.ErrMsg))
            {
                if (result.R1_Code == "1")
                {
                    var pay = new PayDetail
                    {
                        ID = new Guid(result.R6_Order),
                        Money = decimal.Parse(result.R3_Amt),
                        Remark = result.Rp_PayDate,
                        PayID = result.R2_TrxId,
                        PayType = PayType.YeePay.ToString(),
                        Result = (short)PayResult.Success 
                    };

                    int rs = CallBack(pay);
                    if (rs >= 0)
                    {
                        if (result.R9_BType == "1")
                        {
                            //  callback方式:浏览器重定向
                            return RedirectToAction("Detail", "Account", Url.Route(new { Serch = new { Type = "AddMoney", StartTime=DateTime.Now.ToShortDateString()} }));
                        }
                        else if (result.R9_BType == "2")
                        {
                            // * 如果是服务器返回则需要回应一个特定字符串'SUCCESS',且在'SUCCESS'之前不可以有任何其他字符输出,保证首先输出的是'SUCCESS'字符串
                            message = "SUCCESS";
                        }
                    }
                }
                else
                {
                    message="支付失败!";
                }
            }
            else
            {
                message="交易签名无效!";
            }
            return Content(message);
        }
        #endregion

        #region 支付宝
        public ActionResult AliPayCallBack()
        {
            string message = string.Empty;
            ArrayList sArrary = GetRequestGet();
            ///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的//////////////////////
            string partner = "";                //合作身份者ID
            string key = "";    //安全检验码
            string input_charset = "utf-8";                     //字符编码格式 目前支持 gb2312 或 utf-8
            string sign_type = "MD5";                           //加密方式 不需修改
            string transport = Request.Url.Scheme;              //访问模式,根据自己的服务器是否支持ssl访问，若支持请选择https；若不支持请选择http
            //////////////////////////////////////////////////////////////////////////////////////////////

            if (sArrary.Count > 0)//判断是否有带返回参数
            {
                partner = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_MerhantID].Value;
                if (string.IsNullOrEmpty(partner))
                    Log.InfoFormat("在线支付：支付宝商户ID未设置，无法处理回调订单{0},支付宝交易号{1},支付金额{2}", Request.Form["trade_no"], Request.Form["out_trade_no"], Request.Form["total_fee"]);
                key = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Key].Value;
                if (string.IsNullOrEmpty(key))
                    Log.InfoFormat("在线支付：支付宝商户密钥未设置，无法处理回调订单{0},支付宝交易号{1},支付金额{2}", Request.Form["trade_no"], Request.Form["out_trade_no"], Request.Form["total_fee"]);
                var des = new Code.Commen.DES();
                key = des.DecryptString(key, Salt.Keys.GetDesSalt().Key, Salt.Keys.GetDesSalt().Value);
                if (string.IsNullOrEmpty(partner) || string.IsNullOrEmpty(key))
                    throw new AppException("在线支付：支付宝回调，未设置商户ID或密钥");

                var aliNotify = new AlipayClass.AlipayNotify(sArrary, Request.QueryString["notify_id"], partner, key, input_charset, sign_type, transport);
                string responseTxt = aliNotify.ResponseTxt; //获取远程服务器ATN结果，验证是否是支付宝服务器发来的请求
                string sign = Request.QueryString["sign"];  //获取支付宝反馈回来的sign结果
                string mysign = aliNotify.Mysign;           //获取通知返回后计算后（验证）的加密结果

                //写日志记录（若要调试，请取消下面两行注释）
                //string sWord = "responseTxt=" + responseTxt + "\n return_url_log:sign=" + Request.QueryString["sign"] + "&mysign=" + mysign + "\n return回来的参数：" + AlipayFunction.Create_linkstring(sArrary);
                //AlipayFunction.log_result(Server.MapPath("log/" + DateTime.Now.ToString().Replace(":", "")) + ".txt",sWord);

                //判断responsetTxt是否为ture，生成的签名结果mysign与获得的签名结果sign是否一致
                //responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
                //mysign与sign不等，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
                if (responseTxt == "true" && sign == mysign)//验证成功
                {
                    //获取支付宝的通知返回参数
                    string trade_no = Request.QueryString["trade_no"];      //支付宝交易号
                    string order_no = Request.QueryString["out_trade_no"];	//获取订单号
                    string total_fee = Request.QueryString["total_fee"];	//获取总金额
                    string subject = Request.QueryString["subject"];        //商品名称、订单名称
                    string body = Request.QueryString["body"];              //商品描述、订单备注、描述
                    string buyer_email = Request.QueryString["buyer_email"];//买家支付宝账号
                    string trade_status = Request.QueryString["trade_status"];//交易状态
                    
                    //假设：
                    //sOld_trade_status="0"	表示订单未处理；
                    //sOld_trade_status="1"	表示交易成功（TRADE_FINISHED/TRADE_SUCCESS）

                    if (Request.QueryString["trade_status"] == "TRADE_FINISHED" || Request.QueryString["trade_status"] == "TRADE_SUCCESS")
                    {
                        //根据订单号更新订单，把订单状态处理成交易成功
                        var pay = new PayDetail
                        {
                            ID = new Guid(order_no),
                            Money = decimal.Parse(total_fee),
                            PayID = trade_no,
                            PayType = PayType.AliPay.ToString(),
                            Result = (short)PayResult.Success
                        };

                        int rs = CallBack(pay);
                        if (rs >= 0)
                            return RedirectToAction("Detail", "Account", Url.Route(new { Serch = new { Type = "AddMoney", StartTime = DateTime.Now.ToShortDateString() } }));
                    }
                    else
                    {
                        message = "trade_status=" + Request.QueryString["trade_status"];
                    }
                }
                else//验证失败
                {
                    message = "验证失败";
                }
            }
            else
            {
                message = "无返回参数";
            }

            return Content(message);
        }

        public ActionResult AliPayCallBack_Server()
        {
            string message = string.Empty;

            var sArrary = GetRequestPost();
            ///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的//////////////////////
            string partner = "";                //合作身份者ID
            string key = "";    //安全检验码
            string input_charset = "utf-8";                     //字符编码格式 目前支持 gb2312 或 utf-8
            string sign_type = "MD5";                           //加密方式 不需修改
            string transport = Request.Url.Scheme;                         //访问模式,根据自己的服务器是否支持ssl访问，若支持请选择https；若不支持请选择http
            //////////////////////////////////////////////////////////////////////////////////////////////

            if (sArrary.Count > 0)//判断是否有带返回参数
            {
                partner = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_MerhantID].Value;
                if (string.IsNullOrEmpty(partner))
                    Log.InfoFormat("在线支付：支付宝商户ID未设置，无法处理回调订单{0},支付宝交易号{1},支付金额{2}",Request.Form["trade_no"],Request.Form["out_trade_no"],Request.Form["total_fee"]);
                key = CacheManage.OptionSite[Option_Site_Key.Site_Pay_AliPay_Key].Value;
                if (string.IsNullOrEmpty(key))
                    Log.InfoFormat("在线支付：支付宝商户密钥未设置，无法处理回调订单{0},支付宝交易号{1},支付金额{2}", Request.Form["trade_no"], Request.Form["out_trade_no"], Request.Form["total_fee"]);
                var des = new Code.Commen.DES();
                key = des.DecryptString(key, Salt.Keys.GetDesSalt().Key, Salt.Keys.GetDesSalt().Value);
                if (string.IsNullOrEmpty(partner) || string.IsNullOrEmpty(key))
                    throw new AppException("在线支付：支付宝回调，未设置商户ID或密钥");

                var aliNotify = new AlipayClass.AlipayNotify(sArrary, Request.Form["notify_id"], partner, key, input_charset, sign_type, transport);
                string responseTxt = aliNotify.ResponseTxt; //获取远程服务器ATN结果，验证是否是支付宝服务器发来的请求
                string sign = Request.Form["sign"];         //获取支付宝反馈回来的sign结果
                string mysign = aliNotify.Mysign;           //获取通知返回后计算后（验证）的加密结果

                //写日志记录（若要调试，请取消下面两行注释）
                //string sWord = "responseTxt=" + responseTxt + "\n notify_url_log:sign=" + Request.Form["sign"] + "&mysign=" + mysign + "\n notify回来的参数：" + AlipayClass.AlipayFunction.Create_linkstring(sArrary);
                //AlipayClass.AlipayFunction.log_result(Server.MapPath("log/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", sWord);

                //判断responsetTxt是否为ture，生成的签名结果mysign与获得的签名结果sign是否一致
                //responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
                //mysign与sign不等，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
                if (responseTxt == "true" && sign == mysign)//验证成功
                {
                    //获取支付宝的通知返回参数
                    string trade_no = Request.Form["trade_no"];         //支付宝交易号
                    string order_no = Request.Form["out_trade_no"];     //获取订单号
                    string total_fee = Request.Form["total_fee"];       //获取总金额
                    string subject = Request.Form["subject"];           //商品名称、订单名称
                    string body = Request.Form["body"];                 //商品描述、订单备注、描述
                    string buyer_email = Request.Form["buyer_email"];   //买家支付宝账号
                    string trade_status = Request.Form["trade_status"]; //交易状态

                    //假设：
                    //表示交易成功（TRADE_FINISHED/TRADE_SUCCESS）

                    if (Request.Form["trade_status"] == "TRADE_FINISHED" || Request.Form["trade_status"] == "TRADE_SUCCESS")
                    {
                        //根据订单号更新订单，把订单状态处理成交易成功
                        var pay = new PayDetail
                        {
                            ID = new Guid(order_no),
                            Money = decimal.Parse(total_fee),
                            PayID = trade_no,
                            PayType = PayType.AliPay.ToString(),
                            Result = (short)PayResult.Success
                        };

                        int rs = CallBack(pay);
                        message="success";
                    }
                    else
                    {
                        message = "success";  //其他状态判断。普通即时到帐中，其他状态不用判断，直接打印success。
                    }
                }
                else//验证失败
                {
                    message = "fail";
                }
            }
            else
            {
                message = "无通知参数";
            }
            return Content(message);
        }

        /// <summary>
        /// 获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        [NonAction]
        private ArrayList GetRequestPost()
        {
            int i = 0;
            ArrayList sArray = new ArrayList();
            System.Collections.Specialized.NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.Form;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i] + "=" + Request.Form[requestItem[i]]);
            }

            return sArray;
        }

        /// <summary>
        /// 获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        [NonAction]
        private ArrayList GetRequestGet()
        {
            int i = 0;
            ArrayList sArray = new ArrayList();
            System.Collections.Specialized.NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.QueryString;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i] + "=" + Request.QueryString[requestItem[i]]);
            }

            return sArray;
        }
        #endregion

        #region 财富通
        public ActionResult TenPayCallBack()
        {
            var pay = PayType.TenPay.GetDetail();
            if (string.IsNullOrEmpty(pay.Key))
                throw new AppException("未设置财付通商户密钥");
            var des = new Code.Commen.DES();
            pay.Key = des.DecryptString(pay.Key, Salt.Keys.GetDesSalt().Key, Salt.Keys.GetDesSalt().Value);
            
            //密钥
            string key = pay.Key;

            //创建PayResponseHandler实例
            var resHandler = new tenpay.PayResponseHandler(this.ControllerContext.HttpContext);

            resHandler.setKey(key);

            //判断签名
            if (resHandler.isTenpaySign())
            {
                //交易单号
                string transaction_id = resHandler.getParameter("transaction_id");

                //金额金额,以分为单位
                string total_fee = resHandler.getParameter("total_fee");

                //支付结果
                string pay_result = resHandler.getParameter("pay_result");

                //商户数据包 --目前用于保存支付单号
                string data = resHandler.getParameter("attach");

                if ("0".Equals(pay_result))
                {
                    //------------------------------
                    //处理业务开始
                    //------------------------------ 

                    //注意交易单不要重复处理
                    //注意判断返回金额

                    var payd = new PayDetail
                    {
                        ID = new Guid(data),
                        Money = (decimal)(int.Parse(total_fee) / 100.0),
                        PayID = transaction_id,
                        PayType = PayType.TenPay.ToString(),
                        Result = (short)PayResult.Success
                    };

                    int rs = CallBack(payd);

                    //------------------------------
                    //处理业务完毕
                    //------------------------------

                    //调用doShow, 打印meta值跟js代码,告诉财付通处理成功,并在用户浏览器显示$show页面.

                    string return_url = Url.Action("Detail", "Account", Url.Route(new { Serch = new { Type = "AddMoney", StartTime = DateTime.Now.ToShortDateString() } }), null, Request.Url.DnsSafeHost);
                    resHandler.doShow(return_url);
                }
                else
                {
                    //当做不成功处理
                    Response.Write("支付失败");
                }

            }
            else
            {
                Response.Write("认证签名失败");
                //string debugInfo = resHandler.getDebugInfo();
                //Response.Write("<br/>debugInfo:" + debugInfo);
            }

            return Content("");
        }
        #endregion
    }
}
